#include "tcp_client.h"

Tcp_client::Tcp_client(QWidget *parent) : QWidget(parent)
{
    connect(&this->socket,&QTcpSocket::connected,this,[&](){
        emit this->connect_sig();
    });

    connect(&this->socket,&QTcpSocket::disconnected,this,[&](){
        emit this->dis_connect_sig();
    });

    /* connect(&this->socket,&QTcpSocket::readyRead,this,[&](){
        QString message = socket.readAll();
        emit this->read_sig(message);
    }); */
    connect(&this->socket,&QTcpSocket::readyRead,this,&Tcp_client::onReadyRead);
    // 在 Tcp_client 类的构造函数或 start_Connect 函数中，添加错误处理：
    // 在 Tcp_client 类的构造函数或 start_Connect 函数中
    connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleSocketError(QAbstractSocket::SocketError)));
}

void Tcp_client::set_Connect(const QString &HostAddr, quint16 port)
{
    this->HostAddr = HostAddr;
    this->port = port;
}

void Tcp_client::start_Connect()
{
    // 启动连接
    this->socket.connectToHost( this->HostAddr , this->port );

}

void Tcp_client::send_msg(QString message)
{
    QByteArray a; // QByteArray是 Qt 中用于存储字节数据的容器，适合网络传输
    a.clear(); // 清空字节数组a（这行其实可以省略，因为新创建的QByteArray本身就是空的）
    a += message; // 将QString类型的message转换为QByteArray并追加到a中 Qt 会自动处理字符串到字节数组的转换（默认使用 UTF-8 编码）
    qint64 bytesWritten = this->socket.write(a); // 通过当前对象的socket成员（应该是QTcpSocket类型）发送数据 write方法会将字节数组a中的数据通过 TCP 连接发送给服务器
    if (bytesWritten == -1)  // 发送失败处理
    {
       qDebug() << "数据发送失败";
    }
}

// 假设 Tcp_client 类内部有 QTcpSocket 成员 socket，补充以下代码：
void Tcp_client::onReadyRead()
{
    static QByteArray recvBuffer; // 静态缓冲区，累积未处理的字节（解决半包）
    recvBuffer.append(this->socket.readAll()); // 读取所有数据到缓冲区
    // 按约定的分隔符 \r\n 拆分完整消息（解决粘包）
    while (recvBuffer.contains("\r\n")) {
        int sepIndex = recvBuffer.indexOf("\r\n"); // 找到分隔符位置
        QByteArray completeData = recvBuffer.left(sepIndex); // 提取完整消息（不含分隔符）
        recvBuffer.remove(0, sepIndex + 2); // 从缓冲区删除已处理的消息（含 \r\n）

        // 将完整消息转为 QString，发送 read_sig 信号
        QString completeMsg = QString::fromUtf8(completeData);
        emit read_sig(completeMsg);
    }
}


void Tcp_client::handleSocketError(QAbstractSocket::SocketError err)
{
    qDebug() << "[Tcp_client ERROR] Socket 错误类型：" << err
             << "，错误描述：" << socket.errorString();
    emit dis_connect_sig();
}
